package com.laobiao.file_netty_lib.netty.client.handler.fileList;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.laobiao.file_netty_lib.content.LoggerUtil;
import com.laobiao.file_netty_lib.exception.FileBaseException;
import com.laobiao.file_netty_lib.netty.client.ClientBusiness;
import com.laobiao.file_netty_lib.packet.BasePacket;
import com.laobiao.file_netty_lib.packet.PacketType;
import com.laobiao.file_netty_lib.packet.command.ResoultCommand;
import com.laobiao.file_netty_lib.packet.command.download.ClientFileDownloadCommand;
import com.laobiao.file_netty_lib.packet.command.download.ServerFileDownloadResoutCommand;
import com.laobiao.file_netty_lib.packet.command.filelist.FileListCommand;
import com.laobiao.file_netty_lib.packet.data.BaseDataPacket;
import com.laobiao.file_netty_lib.util.CheckCodeUtil;

import io.netty.channel.Channel;

/**
 * 文件下载业务处理类
 * 
 * @author 38079
 *
 */

public class ClientFileListBusiness implements ClientBusiness {
	private final Logger logger = LoggerUtil.getLogger(ClientFileListBusiness.class);

	/**
	 * 客户端下载命令内容
	 */
	private FileListCommand command;
	/**
	 * 连接
	 */
	private Channel channel;

	/**
	 * 当前等待时间
	 */
	private volatile long currMillisecond = 20000;
	/**
	 * 执行超时时间
	 */
	private int timeOutSeconds = 20;

	/**
	 * 整个流程是否停止，异常或正常上传完成后置true
	 */
	private volatile boolean stop = false;

	/**
	 * 是否上传成功，流程完成且正常上传成功是置true
	 */
	private volatile boolean download = false;

	/**
	 * 服务端反馈的消息
	 */
	private String msg = "";
	
	private long startTime;
	
	private ByteArrayOutputStream datas=new ByteArrayOutputStream(); 
	
	private List<FileDetail> files=new ArrayList<FileDetail>();

	public ClientFileListBusiness() {
	}

	public ClientFileListBusiness( FileListCommand command,
			Channel channel) {
		this.channel = channel;
		this.command = command;
		
	}


	@Override
	public void resoultPacket(BasePacket packet) {
		if (packet.getPacketType() == PacketType.COMMAND) {
			 if (packet instanceof ResoultCommand) {
				ResoultCommand resoultCommand = (ResoultCommand) packet;
				if (!resoultCommand.isStatus()) {
					err(resoultCommand.getMessage());
					logger.warning(resoultCommand.getMessage());
					close();
				} else {
					if (resoultCommand.getCode() == ResoultCommand.ResoultCode.Common.COMM_RESOULT) {// 服务端文件发送成功
						
						//开始构造文件列表
						byte[] dataBytes = datas.toByteArray();
						try {
							String dataString=new String(dataBytes,"UTF-8");
							String[] fileStrs = dataString.split(FileListCommand.FILE_SPLIT_CHARACTER);
							if(fileStrs!=null && fileStrs.length>0) {
								for (String fileStr : fileStrs) {
									if(fileStr!=null && !fileStr.trim().contentEquals("")) {
										String[] detailstr = fileStr.split(FileListCommand.DETAIL_SPLIT_CHARACTER);
										FileDetail detail=new FileDetail(command.getRemoteDirPath(), detailstr[0], detailstr[1].equals(FileListCommand.FILE_TYPE_DIR)?FileDetail.FileType.DIR:FileDetail.FileType.FILE);
										files.add(detail);
									}
								}
							}
							sucess(resoultCommand.getMessage());
						} catch (Exception e) {
							// TODO Auto-generated catch block
							err(e.getMessage());
							logger.warning(e.getMessage());
							close();
						}
					}else {
						//其他反馈命令类型全部不管
						reflushCurrMillisecond();
					}
					
				}
			}
		}else if(packet.getPacketType() == PacketType.DATA) {
			if(packet instanceof BaseDataPacket) {
				BaseDataPacket dataPacket=(BaseDataPacket)packet;
				byte[] data = dataPacket.getContent();
				try {
					datas.write(data);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				reflushCurrMillisecond();
			}
		}

	}

	@Override
	public Object executStatus(int executReturnTimeOutSeconds) {
		channel.writeAndFlush(command);
		return getDetails(executReturnTimeOutSeconds);
	}

	/**
	 * 写入远端错误消息
	 * 
	 * @param msg
	 */
	private void err(String msg) {
		setStatus(true, false, msg);
	}

	/**
	 * 执行成功
	 * 
	 * @param msg
	 */
	private void sucess(String msg) {
		setStatus(true, true, msg);
	}

	private void setStatus(boolean stop, boolean download, String msg) {
		this.stop = stop;
		this.download = download;
		this.msg = msg;
		if (stop) {// 停止
			close();
		}
	}
	/**
	 * 更新超时等待时间
	 */
	private void reflushCurrMillisecond() {
		currMillisecond = timeOutSeconds * 1000;
	}

	/**
	 * 检测查询结果
	 * 
	 * @param timeOutSeconds 超时时间
	 * @return
	 */
	public List<FileDetail> getDetails(int timeOutSeconds) {
		this.timeOutSeconds = timeOutSeconds;
		long defaultSleepTime = 100;
		currMillisecond = timeOutSeconds * 1000;
		while (!stop && currMillisecond > 0) {
			currMillisecond -= defaultSleepTime;
			try {
				Thread.currentThread().sleep(defaultSleepTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		if (!stop) {
			throw new FileBaseException("上传下载超时！", FileBaseException.ERR_PARAM_WRONG);
		}
		return files;
	}

	@Override
	public void close() {
		try {
			datas.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public Channel getChannel() {
		return channel;
	}

}
